package com.yonyou.state.core;

import com.yonyou.state.constant.OrderStatusEnum;
import com.yonyou.state.constant.SOStatusEnum;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 工单状态流转管理器--状态机核心组件
 * @author lidwt
 * @date 2021/10/29 19:21
 **/
@Component
public class SOStateManager {

    Map<Integer, AbstractSOOperator> soOperatorMaps = new HashMap<Integer, AbstractSOOperator>();

    Map<Integer, AbstractSOProcessor> soProcessorMaps = new HashMap<Integer, AbstractSOProcessor>();

    public SOStateManager() { }

    /**
     * 状态流转方法
     * @param soId 工单id
     * @param event 流转的工单操作事件
     * @param soStatus 当前工单状态
     * @return 扭转后的工单状态
     */
    public int handleEvent(final String soId, SOStatusEnum event, final int soStatus) {
        if (this.isFinalStatus(soStatus)) {
            throw new IllegalArgumentException("handle event can't process final state order.");
        }
        // 获取对应处理器,根据入参状态和时间获取工单流转的结果状态
        AbstractSOOperator abstractSOOperator = this.getStateOperator(event);
        int resState = abstractSOOperator.handleEvent(soStatus, event);
        // 得到结果状态，在对应的processor中处理工单数据及其相关信息
        AbstractSOProcessor orderProcessor = this.getOrderProcessor(event);
        if (!orderProcessor.check(soId, soStatus)) {
            throw new IllegalStateException(String.format("工单状态流转前置校验失败，工单id:%s，工单当前状态:%s，工单欲流转状态:%s", soId,soStatus,resState));
        }
        if (!orderProcessor.process(soId, resState)) {
            throw new IllegalStateException(String.format("工单状态流转失败，工单id:%s，工单当前状态:%s，工单欲流转状态:%s", soId,soStatus,resState));
        }
        return resState;
    }

    /**
     * 根据入参状态枚举实例获取对应的状态处理器
     * @param event event
     * @return
     */
    private AbstractSOOperator getStateOperator(SOStatusEnum event) {
        AbstractSOOperator operator = null;
        for (Map.Entry<Integer, AbstractSOOperator> entry: soOperatorMaps.entrySet()) {
            if (event.getStatusOrder() == entry.getKey()) {
                operator = entry.getValue();
            }
        }
        if (null == operator) {
            throw new IllegalArgumentException(String.format("can't find proper operator. The parameter state :%s", event.toString()));
        }
        return operator;
    }

    /**
     * 根据入参状态枚举实例获取对应的状态后处理器
     * @param event event
     * @return
     */
    private AbstractSOProcessor getOrderProcessor(SOStatusEnum event) {
        AbstractSOProcessor processor = null;
        for (Map.Entry<Integer, AbstractSOProcessor> entry : soProcessorMaps.entrySet()) {
            if (event.getStatusOrder() == entry.getKey()) {
                processor = entry.getValue();
            }
        }
        if (null == processor) {
            throw new IllegalArgumentException(String.format("can't find proper processor. The parameter state :%s", event.toString()));
        }
        return processor;
    }


    /**
     * 判断是不是已完成工单
     * @param status 工单状态码
     * @return
     */
    private boolean isFinalStatus(int status) {
        return SOStatusEnum.closed.getStatusOrder() == status;
    }

}
